package com.ruoyi.tb.lmt.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.tb.lmt.domain.TbRepairplanlist;
import com.ruoyi.tb.lmt.domain.vo.*;
import com.ruoyi.tb.lmt.mapper.TbParkingMapper;
import com.ruoyi.tb.lmt.mapper.TbRepairplanlistMapper;
import com.ruoyi.tb.lmt.service.ITbLmttypeService;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.tb.lmt.domain.bo.TbLocomotiveBo;
import com.ruoyi.tb.lmt.domain.TbLocomotive;
import com.ruoyi.tb.lmt.mapper.TbLocomotiveMapper;
import com.ruoyi.tb.lmt.service.ITbLocomotiveService;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 大机配属Service业务层处理
 *
 * @author ruoyi
 * @date 2023-11-30
 */
@RequiredArgsConstructor
@Service
public class TbLocomotiveServiceImpl implements ITbLocomotiveService {

    private final TbLocomotiveMapper baseMapper;

    private final TbRepairplanlistMapper tbRepairplanlistMapper;

    @Autowired
    private TbLocomotiveMapper tbLocomotiveMapper;

    @Autowired
    private TbParkingMapper tbParkingMapper;

    /**
     * 查询大机配属
     */
    @Override
    public TbLocomotiveVo queryById(Long ID) {
        return baseMapper.selectVoById(ID);
    }

    /**
     * 查询大机配属列表
     */
    @Override
    public TableDataInfo<TbLocomotiveVo> queryPageList(TbLocomotiveBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<TbLocomotive> lqw = buildQueryWrapper(bo);
        // 在这里添加根据 CreateTime 降序排序
        pageQuery.setOrderByColumn("createTime");
        pageQuery.setIsAsc("desc");
        Page<TbLocomotiveVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询大机配属列表
     */
    @Override
    public List<TbLocomotiveVo> queryList(TbLocomotiveBo bo) {
        LambdaQueryWrapper<TbLocomotive> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<TbLocomotive> buildQueryWrapper(TbLocomotiveBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<TbLocomotive> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getLmtType()), TbLocomotive::getLmtType, bo.getLmtType());
        lqw.like(StringUtils.isNotBlank(bo.getLmtNumber()), TbLocomotive::getLmtNumber, bo.getLmtNumber());
        lqw.like(StringUtils.isNotBlank(bo.getLmtCode()), TbLocomotive::getLmtCode, bo.getLmtCode());
        lqw.eq(StringUtils.isNotBlank(bo.getMadeDate()), TbLocomotive::getMadeDate, bo.getMadeDate());
        lqw.like(StringUtils.isNotBlank(bo.getMadeFactory()), TbLocomotive::getMadeFactory, bo.getMadeFactory());
        lqw.like(StringUtils.isNotBlank(bo.getStatus()), TbLocomotive::getStatus, bo.getStatus());
        lqw.like(StringUtils.isNotBlank(bo.getWorkteamname()), TbLocomotive::getWorkteamname, bo.getWorkteamname());
        lqw.eq(bo.getLastRepairDate() != null, TbLocomotive::getLastRepairDate, bo.getLastRepairDate());
        lqw.orderByDesc(TbLocomotive::getUpdateTime);
        return lqw;
    }

    private LambdaQueryWrapper<TbLocomotive> buildQueryWrapper2(TbLocomotiveBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<TbLocomotive> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getLmtType()), TbLocomotive::getLmtType, bo.getLmtType());
        lqw.like(StringUtils.isNotBlank(bo.getLmtNumber()), TbLocomotive::getLmtNumber, bo.getLmtNumber());
        lqw.like(StringUtils.isNotBlank(bo.getLmtCode()), TbLocomotive::getLmtCode, bo.getLmtCode());
        lqw.eq(StringUtils.isNotBlank(bo.getMadeDate()), TbLocomotive::getMadeDate, bo.getMadeDate());
        lqw.like(StringUtils.isNotBlank(bo.getStatus()), TbLocomotive::getStatus, bo.getStatus());
        lqw.like(StringUtils.isNotBlank(bo.getMadeFactory()), TbLocomotive::getMadeFactory, bo.getMadeFactory());
        lqw.like(StringUtils.isNotBlank(bo.getWorkteamname()), TbLocomotive::getWorkteamname, bo.getWorkteamname());
        lqw.eq(bo.getLastRepairDate() != null, TbLocomotive::getLastRepairDate, bo.getLastRepairDate());
        lqw.orderByDesc(TbLocomotive::getUpdateTime);
        return lqw;
    }

    /**
     * 新增大机配属
     */
    @Override
    public Boolean insertByBo(TbLocomotiveBo bo) {
        TbLocomotive add = BeanUtil.toBean(bo, TbLocomotive.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setID(add.getID());
        }
        return flag;
    }

    /**
     * 修改大机配属
     */
    @Override
    public Boolean updateByBo(TbLocomotiveBo bo) {
        TbLocomotive update = BeanUtil.toBean(bo, TbLocomotive.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(TbLocomotive entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除大机配属
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public TableDataInfo<TbLocomotiveVo> lmtListByStatus(TbLocomotiveBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<TbLocomotive> lqw = buildQueryWrapper2(bo);
        //查询无计划的车辆
        List<TbRepairplanlist> list = tbRepairplanlistMapper.selectList(new QueryWrapper<TbRepairplanlist>().notIn("status", Arrays.asList("已完成", "已取消", "已作废")));
        List<String> lmtNumber = list.stream().map(e -> e.getLmtNumber()).collect(Collectors.toList());
        if (lmtNumber != null && !lmtNumber.isEmpty()) {
            lqw.notIn(TbLocomotive::getLmtNumber, lmtNumber);
        }
        Page<TbLocomotiveVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        List<TbLocomotiveVo> records = result.getRecords();
        for (TbLocomotiveVo tbLocomotiveVo : records) {
            String repairNum = tbLocomotiveVo.getRepairNum(); //最后检修轮次
            Date lastRepairDate = tbLocomotiveVo.getLastRepairDate(); //最后检修时间
            if (StringUtils.isNotBlank(repairNum)) {
                //获取字符串中的数字
                if (tbLocomotiveVo.getLmtType().contains("GMC-96") || tbLocomotiveVo.getLmtType().contains("BS-1200")) {
                    Map<String, String> threeByKey = getThreeByKey(repairNum);
                    tbLocomotiveVo.setLastRepairTime("1");
                    tbLocomotiveVo.setRepairNum(threeByKey.get("key"));
                    tbLocomotiveVo.setLastRepairType(threeByKey.get("val"));
                } else {
                    Map<String, String> fourByKey = getFourByKey(repairNum);
                    tbLocomotiveVo.setLastRepairTime("1");
                    tbLocomotiveVo.setRepairNum(fourByKey.get("key"));
                    tbLocomotiveVo.setLastRepairType(fourByKey.get("val"));
                }
            } else {
                tbLocomotiveVo.setLastRepairTime("1");
                tbLocomotiveVo.setLastRepairType("四级修");
            }
            if (lastRepairDate != null) {
                Calendar ca = Calendar.getInstance();
                ca.setTime(lastRepairDate);
                ca.add(Calendar.DATE, 180);// num为增加的天数，可以改变的
                lastRepairDate = ca.getTime();
                tbLocomotiveVo.setLastRepairDate(lastRepairDate);
            } else {
                tbLocomotiveVo.setLastRepairDate(new Date());
            }
        }
        return TableDataInfo.build(result);
    }

    @Override
    public ArrayList<LmtNumberVo> selectByLmtType(String lmtType) {
        return tbLocomotiveMapper.selectByLmtType(lmtType);
    }

    @Override
    public ArrayList<LmtNumberVo> selectByLmtNumber(String lmtNumber) {
        return tbLocomotiveMapper.selectByLmtNumber(lmtNumber);
    }

    @Override
    public ArrayList<LmtNumberVo> selectBy() {
        return tbLocomotiveMapper.selectBy();
    }

    @Override
    public Long selectByLmtId(Long lmtRepairId) {
        String lmtNumber = tbRepairplanlistMapper.selectByLmtId(lmtRepairId);
        return tbLocomotiveMapper.selectByLmtId(lmtNumber);
    }

    @Override
    public TbLocomotiveVo selectLocomotive(String lmtNumber) {
        return tbLocomotiveMapper.selectLocomotive(lmtNumber);
    }

    @Override
    public LocNumberVo selectLocNumber() {
        LocNumberVo locNumberVo = new LocNumberVo();
        //获得数量
        int overhaulCount = tbLocomotiveMapper.selectOverhaulCount();
        int allCount = tbLocomotiveMapper.selectAllCount();

        locNumberVo.setOverhaulCount(overhaulCount);
        locNumberVo.setAllCount(allCount);

        // 确保分母不为零
        if (allCount > 0) {
            double rate = (double) overhaulCount / allCount * 100;
            int rateCount = (int) Math.ceil(rate); // 向上取整
            locNumberVo.setRateCount(rateCount);
        } else {
            locNumberVo.setRateCount(0); // 如果allCount为0，则设置rateCount为0以避免除以0
        }

        return locNumberVo;
    }

    @Override
    public CarNumberVo selectCarNumber() {
        CarNumberVo carNumberVo = new CarNumberVo();

        //存在数量
        int carCount = tbParkingMapper.selectCarNumber();
        carNumberVo.setCarCount(carCount);

        //获得百分比
        int allCount = 110;
        double rate = (double) carCount / allCount * 100;
        int rateCount = (int) Math.ceil(rate); // 向上取整
        carNumberVo.setRateCount(rateCount);
        return carNumberVo;
    }

    @Override
    public int updateByBoLmtNumber(TbLocomotiveBo lmtBo) {
        return baseMapper.updateByBoLmtNumber(lmtBo);
    }

    @Override
    public boolean existsById(Long id) {
        return tbLocomotiveMapper.existsById(id);
    }

    @Override
    public void export(HttpServletRequest request, HttpServletResponse response) {
        Workbook workbook = new XSSFWorkbook();

        // 创建一个工作表sheet
        Sheet sheet = workbook.createSheet("大机配属");

        // 创建标题行
        Row titleRow = sheet.createRow(0);

        // 定义标题行的列名
        String[] columnHeaders = {
            "车型", "车号", "出场编号", "出场年月", "使用日期", "制造厂家", "整车长度", "大机重量", "配属车间名称", "上次修程", "上次检修日期", "状态", "备注", "长度系数"
        };

        // 设置单元格样式（可选）
        CellStyle headerStyle = workbook.createCellStyle();
        Font headerFont = workbook.createFont();
        headerFont.setBold(true);
        headerStyle.setFont(headerFont);

        // 创建标题行单元格并写入列名
        for (int i = 0; i < columnHeaders.length; i++) {
            Cell cell = titleRow.createCell(i);
            cell.setCellValue(columnHeaders[i]);
            cell.setCellStyle(headerStyle);
        }
        // 设置所有行高
        for (Row row : sheet) {
            row.setHeightInPoints(20);
        }

        // 设置所有列宽
        for (Sheet sh : workbook) {
            for (int i = 0; i < 300; i++) {
                sh.setColumnWidth(i, 14 * 256);
            }
        }

        OutputStream os = null;
        try {
            os = response.getOutputStream();
            workbook.write(os);
            os.flush();
            //os.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public TableDataInfo<TbLocomotiveVo> listLocomotive(TbLocomotiveBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<TbLocomotive> lqw = buildQueryWrapper(bo);
        // 在这里添加根据 CreateTime 降序排序
        pageQuery.setOrderByColumn("createTime");
        pageQuery.setIsAsc("desc");
        lqw.lt(TbLocomotive::getZdfRepairDate, LocalDate.now()).or().lt(TbLocomotive::getTsRepairDate, LocalDate.now()).or().lt(TbLocomotive::getNextPlanRepairDate, LocalDate.now());

        Page<TbLocomotiveVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 检修到期的车辆
     * @param bo
     * @return
     */
    @Override
    public List<TbLocomotiveDueVo> listLocomotive(TbLocomotiveBo bo) {
        LambdaQueryWrapper<TbLocomotive> lqw = buildQueryWrapper(bo);
        // 在这里添加根据 CreateTime 降序排序
        lqw.lt(TbLocomotive::getNextPlanRepairDate, DateUtils.addDays(DateUtils.getNowDate(), 30));
        return null;
    }

    @Override
    public List<TbLocomotiveVo> listLocomotiveExport(TbLocomotiveBo bo) {
        LambdaQueryWrapper<TbLocomotive> lqw = buildQueryWrapper(bo);
        lqw.lt(TbLocomotive::getZdfRepairDate, LocalDate.now()).or().lt(TbLocomotive::getTsRepairDate, LocalDate.now());
        return baseMapper.selectVoList(lqw);
    }

    @Override
    public int countAll() {
        return baseMapper.selectAllCount();
    }

    @Override
    public TableDataInfo<TbLocomotiveVo> getDue(TbLocomotiveBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<TbLocomotive> lqw = buildQueryWrapper(bo);
        // 在这里添加根据 CreateTime 降序排序
        lqw.lt(TbLocomotive::getNextPlanRepairDate, DateUtils.addDays(DateUtils.getNowDate(),20)).or().lt(TbLocomotive::getLastRepairDate,DateUtils.addDays(DateUtils.getNowDate(),-170));
        Page<TbLocomotiveVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        for (TbLocomotiveVo vo : result.getRecords()) {
            if (StringUtils.isNotBlank(vo.getRepairNum())){
                if (vo.getLmtType().contains("GMC-96") || vo.getLmtType().contains("BS-1200")) {
                    Map<String, String> threeByKey = getThreeByKey(vo.getRepairNum());
                    vo.setRepairType(threeByKey.get("val"));
                } else {
                    Map<String, String> fourByKey = getFourByKey(vo.getRepairNum());
                    vo.setRepairType(fourByKey.get("val"));
                }
            }else {
                vo.setRepairType("暂无下次修程");
            }
        }
        return TableDataInfo.build(result);
    }


    public Map<String, String> three = new HashMap<String, String>();
    public Map<String, String> four = new HashMap<String, String>();

    public Map<String, String> getThreeByKey(String key) {
        if (three.size() == 0) {
            sendThree();
        }
        Map<String, String> params = new HashMap<>();
        int i = Integer.parseInt(key);

        if (i >= 6) {
            i = 1;
        } else {
            i++;
        }

        params.put("key", String.valueOf(i));
        params.put("val", three.get(String.valueOf(i)));
        return params;
    }

    public Map<String, String> getFourByKey(String key) {
        if (four.size() == 0) {
            sendFour();
        }
        Map<String, String> params = new HashMap<>();
        int i = Integer.parseInt(key);
        if (i >= 8) {
            i = 1;
        } else {
            i++;
        }

        params.put("key", String.valueOf(i));
        params.put("val", four.get(String.valueOf(i)));
        return params;
    }

    public void sendThree() {
        three.put("1", "四级修");
        three.put("2", "二级修");
        three.put("3", "三级修");
        three.put("4", "二级修");
        three.put("5", "三级修");
        three.put("6", "二级修");
    }

    public void sendFour() {
        four.put("1", "四级修");
        four.put("2", "二级修");
        four.put("3", "三级修");
        four.put("4", "二级修");
        four.put("5", "三级修");
        four.put("6", "二级修");
        four.put("7", "三级修");
        four.put("8", "二级修");
    }
}
